using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using Microsoft.MediaCenter;
using Microsoft.MediaCenter.Hosting;
using Microsoft.MediaCenter.UI;
using RadioStream.Code;
using RadioStream.SongIDService;
using RadioStream.WebReference;
using System.Xml;
using System.Reflection;
using System.Windows.Forms;
using RadioStream.Code.Utils;



namespace RadioStream
{
    public class Application : ModelItem
    {
        private AddInHost host;
        private HistoryOrientedPageSession session;

        //WebServices
        private SongIDService.SongIDService m_SongIDService;
        private StationGuideService2 m_StationGuideService;

        private CSongInfo m_SongInfo;
        /** This method provides the CSongInfo currently played. */
        public CSongInfo GetSongInfo
        {
            get
            {
                return m_SongInfo;
            }
            set
            {
            }
        }

        public Application()
            : this(null, null)
        {
        }     

        private System.Threading.Thread m_RefresherThread;
        private CRefresher m_Refresher;
        private ArrayListDataSet m_StationListDataSet;
        private ArrayListDataSet m_RegionListDataSet;
        private System.Threading.Thread m_PlayerThread;

        public Application(HistoryOrientedPageSession session, AddInHost host)
        {
            this.session = session;
            this.host = host;

            // create Objects by default
            m_StationList = new Choice();
            m_SongInfo = new CSongInfo();
            m_Refresher = new CRefresher(this);

            //______________________________________________________
            //Code vor dem anzeigen  
            try
            {
                // AddStations
                m_SongIDService = new SongIDService.SongIDService();
                m_StationGuideService = new StationGuideService2();
                m_StationListDataSet = new ArrayListDataSet();
                m_RegionListDataSet = new ArrayListDataSet();              
                //System.Threading.Thread ImportThread = new System.Threading.Thread(new ThreadStart(ImportStationList));
                //ImportThread.Start();
                ImportStationList();

                XMLUtil.WriteXML(@"D:\test.xml", m_StationListDataSet, m_RegionListDataSet);

                GoToMenu(); // here the main method is called and the MCML is displayed
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        private void ImportStationList()
        {
            XmlDocument doc = XMLUtil.GetXMLDocument("RadioStreamStations.xml");
            XmlNamespaceManager nsM = new XmlNamespaceManager(doc.NameTable);
            nsM.AddNamespace("rs", "RadioStream");
            //retrieve all station information 
            List<XmlAttributeCollection> Stations = XMLUtil.GetElementAttributes(doc, "/rs:RadioStream/rs:Stations/rs:Station", nsM);

            foreach (XmlAttributeCollection Station in Stations)
            {
                //for each Station fetch Attributes
                int CurrentID = -1;
                int CurrentRegionID = -1;
                bool isFav = false;
                foreach (XmlAttribute StationAttribute in Station)
                {
                    switch (StationAttribute.Name)
                    {
                        case "Favorite":
                            isFav = Convert.ToBoolean(StationAttribute.Value);
                            break;
                        case "ID":
                            CurrentID = Convert.ToInt32(StationAttribute.Value);
                            break;
                        case "RegionID":
                            CurrentRegionID = Convert.ToInt32(StationAttribute.Value);
                            break;
                    }
                }
                m_StationListDataSet.Add(new CStationInfo(CurrentID,CurrentRegionID, isFav));
                //RefreshStationList();
            }
            CStationInfo.StationComparer myComparer = new CStationInfo.StationComparer();
            m_StationListDataSet.Sort(myComparer);
            m_StationList.Options = m_StationListDataSet;
            RefreshStationList();
        }

        private CStationInfo m_SelectedStation;
        public CStationInfo SelectedStation
        {
            get
            {
                 return m_SelectedStation;
            }
            set
            {
                if (null != value)
                {
                    m_SelectedStation = value;
                    GoToStreaming();
                }
                FirePropertyChanged("SelectedStation");
            }
        }
        
        public void RefreshSongInfo()
        {
            if (!Microsoft.MediaCenter.UI.Application.IsApplicationThread)
            {
                Microsoft.MediaCenter.UI.Application.DeferredInvoke(new DeferredHandler(RefreshSongInfoDeferredInvoke));
            }
            else
            {
                RefreshSongInfoDeferredInvoke(null);
            }
            FirePropertyChanged("GetSongInfo");
        }

        public void RefreshStationList()
        {
            if (!Microsoft.MediaCenter.UI.Application.IsApplicationThread)
            {
                Microsoft.MediaCenter.UI.Application.DeferredInvoke(new DeferredHandler(RefreshSongInfoDeferredInvoke));
            }
            else
            {
                RefreshSongInfoDeferredInvoke(null);
            }
            FirePropertyChanged("StationList");
        }

        private void PlayStream()
        {
            if (null != m_SelectedStation)
            {
                StationInfo myStationInfo = m_StationGuideService.GetStationInfoByID(m_SelectedStation.StationID.ToString(), null, null);
                StationStream[] Streams = myStationInfo.StationStreamURLs;
                for (int i = 0; i < Streams.Length; i++)
                {
                    StationStream Stream = Streams[i];
                    if (("WMA" == Stream.StreamFormat) && (64 == Stream.StreamBitrate)) // MediaCenter is only able to play asx streams
                    {
                        string stURL = Stream.StreamURL;
                        if (null != MediaCenterEnvironment)
                        {
                            MediaCenterEnvironment.PlayMedia(MediaType.Audio, stURL, false);
                        }
                        break;
                    }
                }
            }
            else
            {
                Exception e = new Exception("No station selected, cannot play stream.");
                throw (e);
            }
        }
        
        private void RefreshSongInfoDeferredInvoke(object args)
        {
            // create a new XML object and retrieve information for current station
            
            if (null != m_SelectedStation)
            {
                XmlDocument doc = XMLUtil.GetXMLDocument("http://songid.play.it/NowPlayingWeb/SongIDService.asmx/GetNowPlayingEventForStation?stationID=" + m_SelectedStation.StationID.ToString());
                XmlNamespaceManager nsM = new XmlNamespaceManager(doc.NameTable);
                nsM.AddNamespace("wm", "http://wilshiremedia.com/");
                //retrieve all information 
                int TimeRemainingInSeconds = 5;
                string CoverURL = XMLUtil.GetFirstElementText(doc, "/wm:NowPlayingEventPackage/wm:CurrentEventPackage/wm:AlbumArt", nsM);
                string strTitle = XMLUtil.GetFirstElementText(doc, "/wm:NowPlayingEventPackage/wm:CurrentEventPackage/wm:Title", nsM);
                string strArtist = XMLUtil.GetFirstElementText(doc, "/wm:NowPlayingEventPackage/wm:CurrentEventPackage/wm:Artist", nsM);
                string strAlbum = XMLUtil.GetFirstElementText(doc, "/wm:NowPlayingEventPackage/wm:CurrentEventPackage/wm:AlbumTitle", nsM);
                string TimeRemaining = XMLUtil.GetFirstElementText(doc, "/wm:NowPlayingEventPackage/wm:TimeRemainingInSeconds", nsM);
                if ("" != TimeRemaining) TimeRemainingInSeconds = Convert.ToInt32(TimeRemaining);


                // update SongInfo securely
                lock (m_SongInfo)
                {
                    m_SongInfo = new CSongInfo(strArtist, strTitle, strAlbum, 0, CoverURL, TimeRemainingInSeconds);
                }
            }
        }

        public MediaCenterEnvironment MediaCenterEnvironment
        {
            get
            {
                if (host == null) return null;
                return host.MediaCenterEnvironment;
            }
        }

        protected Choice m_StationList;
        public Choice StationList
        {
            get
            {
                    return m_StationList;
            }
            set
            {
                if (null != value)
                {
                    m_StationList = value;
                }
            }
        }

        public void GoToMenu()
        {        
            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["Application"] = this;

            if (session != null)
            {
                session.GoToPage("resx://RadioStream/RadioStream.Resources/RadioStream_Stations", properties);
            }
            else
            {
                Exception e = new Exception("Cannot acces MediaCenterEnvironment in GoToPage(), session is null");
                throw (e);
            }
        }
        
        public void GoToStreaming()
        {
            // spin off a thread to display the song information
            m_RefresherThread = new System.Threading.Thread(new ThreadStart(m_Refresher.Run));
            m_RefresherThread.Start();

            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["Application"] = this;

            if (session != null)
            {
                session.GoToPage("resx://RadioStream/RadioStream.Resources/RadioStream_Streaming", properties);
            }
            else
            {
                Exception e = new Exception("Cannot acces MediaCenterEnvironment in GoToStreaming(), session is null");
                throw (e);
            }

            // spin off a thread to play the music
            m_PlayerThread = new System.Threading.Thread(new ThreadStart(PlayStream));
            m_PlayerThread.Start();
        }
    }
}